package com.itfreer.arcgis.utils;

import com.esri.arcgisruntime.geometry.Geometry;
import com.esri.arcgisruntime.geometry.GeometryEngine;
import com.esri.arcgisruntime.geometry.GeometryType;
import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.geometry.PointCollection;
import com.esri.arcgisruntime.geometry.Polygon;
import com.esri.arcgisruntime.geometry.Polyline;
import com.esri.arcgisruntime.geometry.SpatialReference;

import java.util.ArrayList;
import java.util.List;

/**
 * Geometry 辅助类
 */
public class GeometryUtils
{
    /**
     * 判断要素合并后是否为单一部分要素
     *
     * @param geometries
     * @return
     */
    public static Boolean CheckGeometryUnionIsSample(List<Geometry> geometries)
    {
        if (geometries == null || geometries.size() == 0 || geometries.size() == 1)
            return false;

        for (Integer i = 0; i < geometries.size(); i++)
        {
            if (geometries.get(i) == null || geometries.get(i).isEmpty())
                return false;
        }

        Geometry geometry = GeometryEngine.union(geometries);
        if (geometry == null || geometry.isEmpty())
            return false;

        if (geometry.getGeometryType() == GeometryType.POLYGON)
        {
            Polygon polygon = (Polygon) geometry;
            if (polygon.getParts().size() > 1)
                return false;

        } else if (geometry.getGeometryType() == GeometryType.POLYLINE)
        {
            Polyline polyline = (Polyline) geometry;
            if (polyline.getParts().size() > 1)
                return false;
        }

        return true;
    }

    /**
     * 通过中心点和半径计算得出圆形的边线点集合
     *
     * @param center
     * @param radius
     * @return
     */
    public static Point[] getCirclePoints(Point center, double radius)
    {
        Point[] points = new Point[50];
        double sin;
        double cos;
        double x;
        double y;
        for (double i = 0; i < 50; i++)
        {
            sin = Math.sin(Math.PI * 2 * i / 50);
            cos = Math.cos(Math.PI * 2 * i / 50);
            x = center.getX() + radius * sin;
            y = center.getY() + radius * cos;
            points[(int) i] = new Point(x, y);
        }
        return points;
    }

    /**
     * 通过中心点和半径计算得出圆形图形
     * @param center
     * @param radius
     * @return
     */
    public static Polygon getCirclePolygon(Point center, double radius, SpatialReference spatialReference)
    {
        Point[] points = getCirclePoints(center,radius);
        PointCollection mPointCollection = new PointCollection(spatialReference);
        for (Point p : points) {
            mPointCollection.add(p);
        }
        Polygon polygon = new Polygon(mPointCollection);
        return polygon;
    }

    /**
     * 面转点集合
     * @param polyline 线对象
     * @return
     */
    public static List<Point> polylineToPoints(Polyline polyline)
    {
        List<Point> points = new ArrayList<>();
        for  (Point pt : polyline.getParts().getPartsAsPoints())
        {
            points.add(pt);
        }
        return  points;
    }

    /**
     * 面转点集合
     * @param polygon 面对象
     * @return
     */
    public static List<Point> polygonToPoints(Polygon polygon)
    {
        List<Point> points = new ArrayList<>();
        for  (Point pt : polygon.getParts().getPartsAsPoints())
        {
            points.add(pt);
        }
        return  points;
    }

    /**
     * 图形转点集
     * @param geometry
     * @return
     */
    public static List<Point> geometryToPoints(Geometry geometry)
    {
        List<Point> points = new ArrayList<>();
         if(geometry.getGeometryType() == GeometryType.POINT)
         {
             points.add((Point) geometry);
             return  points;
         }
         else if(geometry.getGeometryType() == GeometryType.POLYLINE)
         {
            return  polylineToPoints((Polyline)geometry);
         }
         else if(geometry.getGeometryType() == GeometryType.POLYGON)
         {
             return  polygonToPoints((Polygon)geometry);
         }
         return  null;
    }

    /**
     * 点转面集合
     * @param points 点集合
     * @return
     */
    public static Polygon pointsToPolygon(List<Point> points,SpatialReference spatialReference)
    {
        PointCollection pointCollection = new PointCollection(spatialReference);
        for(Integer i = 0;i<points.size();i++)
        {
            pointCollection.add(points.get(i));
        }
        return  new Polygon(pointCollection,spatialReference);
    }

    /**
     * 点转线集合
     * @param points 点集合
     * @return
     */
    public static Polyline pointsToPolyline(List<Point> points,SpatialReference spatialReference)
    {
        PointCollection pointCollection = new PointCollection(spatialReference);
        for(Integer i = 0;i<points.size();i++)
        {
            pointCollection.add(points.get(i));
        }
        return  new Polyline(pointCollection);
    }
}
